﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace MusicRipperDataAccess
{

    public class AlbumHandler
    {
        #region Fields (1)

        List<Album> myAlbums;

        #endregion Fields

        #region Constructors (1)

        public AlbumHandler()
        {
            myAlbums = new List<Album>();
            GetFromFile();
        }

        #endregion Constructors

        #region Methods (2)

        // Public Methods (2) 

        public void AddToAlbums(Album inA)
        {
           if(! DoesThisAlbumExist(inA))
           {
            myAlbums.Add(inA);
           }
        }

        public void WriteToFile()
        {
            Stream sw = new FileStream("Albums.xml", FileMode.Create);
            System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(myAlbums.GetType());
            x.Serialize(sw, myAlbums);
        }

        public void GetFromFile()
        {
            if (File.Exists("Albums.xml"))
            {
                Stream sw = new FileStream("Albums.xml", FileMode.Open);
                System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(myAlbums.GetType());
                myAlbums = (List<Album>)x.Deserialize(sw);
            }
      
        }

       public bool DoesThisAlbumExist(Album inA)
       {
          return myAlbums.Contains(inA);
       }
        public List<string> GetAlbumTitles()
        {
            List<string> myAlbumTitles = new List<string>();
            foreach (Album a in myAlbums)
            {
                myAlbumTitles.Add(a.Title);
            }

            

            return myAlbumTitles;
        }

        #endregion Methods
    }

    public class Album:IDisposable ,IEquatable<Album>
    {
        #region Fields (1)

        private List<Track> myTracks;
        private NameTracker myNameTracker;

        #endregion Fields

        #region Constructors (1)

        public Album()
        {
            myTracks = new List<Track>();
            myNameTracker = new NameTracker();
            this.GetNameTrackerFromFile();
        }
       public Album(string inTitle, string inArtist) :this()
        {
           this.Title = inTitle;
           this.Artist = inArtist;
         }

        #endregion Constructors

        #region Properties (3)
        public String Title { get; set; }
        public String Artist { get; set; }
        public List<Track> MyTracks
        {
            get { return myTracks; }
            set { myTracks = value; }
        }
        #endregion Properties

        #region Methods (4)

        // Public Methods (2) 

        public void AddNewTrack(string inArtist, string inOrgTitle, string inNewTitle)
        {

            myTracks.Add(new Track(inArtist, inOrgTitle, inNewTitle));
        }

        public void SetTracks(List<string> inTrackTitles)
        {
            int i = 0;
            foreach (string songTitle in inTrackTitles)
            {
                this.AddNewTrack(this.Artist, songTitle, GetNewNameForTrack(i++));
            }
        }

        public void WriteToFile()
        {
            Stream sw = new FileStream("Albums.xml", FileMode.Create);
            System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(this.GetType());
            x.Serialize(sw, this);
        }
        // Private Methods (2) 

        private char GetArtistChar(string inString)
        {
            char c = inString[0];
            if (inString.StartsWith("the ", StringComparison.CurrentCultureIgnoreCase))
                c = inString[4];
            if (inString.StartsWith("an ", StringComparison.CurrentCultureIgnoreCase))
                c = inString[3];
            if (inString.StartsWith("a ", StringComparison.CurrentCultureIgnoreCase))
                c = inString[2];
            return c;
        }

        private string GetNewNameForTrack(int inNum)
        {
            char begin = GetArtistChar(Artist);
            char end = this.Title[0];
            StringBuilder sb = new StringBuilder();
            sb.Append(begin);
            sb.Append(end);
          
            int value = this.myNameTracker.GetValue(sb.ToString());
            return (begin + value.ToString().PadLeft(4, '0') + end + ".wav");
        }

        private void GetNameTrackerFromFile()
        {
            FileStream fs = null;
            try
            {
                fs = new FileStream("NameTracker.xml", FileMode.OpenOrCreate);
                XmlTextReader reader = new XmlTextReader(fs);
                var serializer = new DataContractSerializer(typeof(NameTracker));

                this.myNameTracker = (NameTracker)serializer.ReadObject(reader);
            }
            catch (Exception)
            { }
            finally
            {
                fs.Close();
                fs = null;
            }
           
        }

        public void Dispose()
        {
            var serializer = new DataContractSerializer(typeof(NameTracker));
            string myString;
            using (var sw = new StringWriter())
            {
                using (var writer = new XmlTextWriter(sw))
                {
                    writer.Formatting = Formatting.Indented; // indent the Xml so it's human readable
                    serializer.WriteObject(writer, myNameTracker);
                    writer.Flush();
                    myString = sw.ToString();
                    using (StreamWriter fileWriter = new StreamWriter("NameTracker.xml", false))
                    {
                        fileWriter.AutoFlush = true;
                        fileWriter.Write(myString);
                        fileWriter.Close();
                    }
                }
            }
        }

        #endregion Methods

        #region IEquatable<Album> Members

        public bool Equals( Album other )
        {
           if (other == null)
              return false;
           if (this.Artist == other.Artist && this.Title == other.Title)
              return true;
           else
              return false;
        }

        public override bool Equals( object obj )
        {
           if (obj == null)
              return false;
           Album temp = obj as Album;
           if (temp == null)
              return false;
           else
              return Equals( temp );
        }

        #endregion
    }
    public class NameTrackerHandler
    {

    }
    [DataContract]
    public class  NameTracker
    {
        [DataMember]
        public Dictionary<string, int> myValues { get; set; }

        public NameTracker()
        {
           myValues = new Dictionary<string, int>( );
        }

        public int GetValue(string inHeader)
        {
            int i;
            if (myValues.TryGetValue(inHeader, out i))
            {
                i++;
                myValues[inHeader] = i;
            }

            else
                myValues.Add(inHeader, i);

            return i;

        }

     

       
    }
}
